var Core = (function () {
	var lib = Lib.create();
	var moduleData = {};
	var to_s = function (anything) {
		return Object.prototype.toString.call(anything);
	};
	var debug = true;

	var log = function (severity, message) {
		if (debug) {
			console[severity](message);
		} else {
			// send to the server
		}
	};

	return {
		debug : function (on) {
			debug = on ? true : false;
		},
		create_module : function (moduleID, creator) {
			var temp;
			if (typeof moduleID === 'string' && typeof creator === 'function') {
				temp = creator(Sandbox.create(this, moduleID));
				if (temp.init && typeof temp.init === 'function' && temp.destroy && typeof temp.destroy === 'function') {
					temp = null;
					moduleData[moduleID] = {
						create : creator,
						instance : null
					};
				} else {
					this.log(1, "Module '" + moduleID + "' Registration : FAILED : instance has no init or destory functions");
				}
			} else {
				this.log(1, "Module '" + moduleID + "' Registration : FAILED : one or more arguments are of incorrect type");
			}
		},
		start : function (moduleID) {
			var mod = moduleData[moduleID];
			if (mod) {
				mod.instance = mod.create(Sandbox.create(this, moduleID));
				mod.instance.init();
			}
		},
		start_all : function () {
			var moduleID;
			for (moduleID in moduleData) {
				if (moduleData.hasOwnProperty(moduleID)) {
					this.start(moduleID);
				}
			}
		},
		stop : function (moduleID) {
			var data;
			if (data = moduleData[moduleId] && data.instance) {
				data.instance.destroy();
				data.instance = null;
			} else {
				this.log(1, "Stop Module '" + moduleID + "': FAILED : module does not exist or has not been started");
			}
		},
		stop_all : function () {
			var moduleID;
			for (moduleID in moduleData) {
				if (moduleData.hasOwnProperty(moduleID)) {
					this.stop(moduleID);
				}
			}
		},
		registerEvents : function (evts, mod) {
			if (this.is_obj(evts) && mod) {
				if (moduleData[mod]) {
					moduleData[mod].events = evts;
				} else {
					this.log(1, "");
				}
			} else {
				this.log(1, "");
			}
		},
		triggerEvent : function (evt) {
			var mod;
			for (mod in moduleData) {
				if (moduleData.hasOwnProperty(mod)) {
					mod = moduleData[mod];
					if (mod.events && mod.events[evt.type]) {
						mod.events[evt.type](evt.data);
					}
				}
			}
		},
		removeEvents : function (evts, mod) {
			if (this.is_obj(evts) && mod && (mod = moduleData[mod]) && mod.events) {
				delete mod.events;
			}
		},
		logInfo : function(message) {
			log('log', message);
		},
		logWarn : function(message) {
			log('warn', message);
		},
		logError : function(message) {
			log('error', message);
		},
		dom: lib.dom,
		is_arr: lib.is_arr,
		is_obj: lib.is_obj
	};

}());
